<template>
    <div class="treeChart">
        <table v-if="treeData.mac">
            <tr>
                <td
                    :colspan="Array.isArray(treeData.children) ? treeData.children.length * 2 : 1"
                    :class="{
                        parentLevel: Array.isArray(treeData.children) && treeData.children.length,
                        extend: Array.isArray(treeData.children) && treeData.children.length && treeData.extend
                    }"
                >
                    <div :class="{ node: true, hasMate: treeData.mate }">
                        <div class="leaf" :class="Array.isArray(treeData.class) ? treeData.class : []" @click="$emit('click-node', treeData)">
                            <img class="icon" alt="network" :src="iconMap.get(treeData.isRoute) || iconMap.get(treeData.type) || iconMap.get('DEFAULT')" />

                            <div class="vertical-line"></div>
                            <div class="info">
                                <div>{{ treeData.host }}</div>
                                <div>{{ treeData.ip }}</div>
                                <div v-if="treeData.mac">{{ treeData.mac.toUpperCase() }}</div>
                                <div v-if="treeData.linkType">{{ treeData.linkType }}</div>
                            </div>
                        </div>
                    </div>
                    <div class="extend_handle" v-if="Array.isArray(treeData.children) && treeData.children.length" @click="toggleExtend(treeData)"></div>
                </td>
            </tr>
            <tr v-if="Array.isArray(treeData.children) && treeData.children.length && treeData.extend">
                <td v-for="(children, index) in treeData.children" :key="index" colspan="2" class="childLevel">
                    <TreeChart :json="children" @click-node="$emit('click-node', $event)" />
                </td>
            </tr>
        </table>
    </div>
</template>

<script>
// 信号图标对象集 -- MobileSetting
const topoTypeIconObj = {
    WLAN2G: require('@/assets/images/TopologyMap_2.4g.png'),
    WLAN5G: require('@/assets/images/TopologyMap_5g.png'),
    WLAN6G: require('@/assets/images/TopologyMap_6g.png'),
    ETHER: require('@/assets/images/TopologyMap_ether.png'),
    ROUTE: require('@/assets/images/TopologyMap_wifiRouter.png'),
    DEFAULT: require('@/assets/images/TopologyMap_default.png')
};
export default {
    name: 'TreeChart',
    props: ['json'],
    data() {
        return {
            treeData: {},
            iconMap: new Map([
                ['WLAN2G', topoTypeIconObj.WLAN2G],
                ['WLAN5G', topoTypeIconObj.WLAN5G],
                ['WLAN6G', topoTypeIconObj.WLAN6G],
                ['ETHER', topoTypeIconObj.ETHER],
                ['ROUTE', topoTypeIconObj.ROUTE],
                ['DEFAULT', topoTypeIconObj.DEFAULT]
            ])
        };
    },
    watch: {
        json: {
            handler: function (Props) {
                let extendKey = function (jsonData) {
                    jsonData.extend = jsonData.extend === void 0 ? true : !!jsonData.extend;
                    if (Array.isArray(jsonData.children)) {
                        jsonData.children.forEach((c) => {
                            extendKey(c);
                        });
                    }
                    return jsonData;
                };
                if (Props) {
                    this.treeData = extendKey(Props);
                }
            },
            immediate: true
        }
    },
    methods: {
        toggleExtend: function (treeData) {
            treeData.extend = !treeData.extend;
            this.$forceUpdate();
        }
    }
};
</script>
<style lang="less" scoped>
.treeChart {
    table {
        border-collapse: separate !important;
        border-spacing: 0 !important;
        margin: 0 auto;
    }
    td {
        position: relative;
        vertical-align: top;
        padding: 0 0 50px 0;
        text-align: center;
    }
    overflow: auto;
}

.extend_handle {
    position: absolute;
    left: 50%;
    bottom: 20px;
    width: 10px;
    height: 10px;
    padding: 10px;
    transform: translate3d(-15px, 0, 0);
    cursor: pointer;
    &::before {
        content: '';
        display: block;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        border: 2px solid;
        border-color: #ccc #ccc transparent transparent;
        transform: rotateZ(135deg);
        transform-origin: 50% 50% 0;
        transition: transform ease 300ms;
    }
    &:hover::before {
        border-color: #333 #333 transparent transparent;
    }
}
.extend {
    .extend_handle {
        &::before {
            transform: rotateZ(-45deg);
        }
    }
    &::after {
        content: '';
        position: absolute;
        left: 50%;
        bottom: 15px;
        height: 15px;
        border-left: 2px solid #ccc;
        transform: translate3d(-1px, 0, 0);
    }
}

.childLevel {
    &::before {
        content: '';
        position: absolute;
        left: 50%;
        bottom: 100%;
        height: 15px;
        border-left: 2px solid #ccc;
        transform: translate3d(-1px, 0, 0);
    }
    &::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: -15px;
        border-top: 2px solid #ccc;
    }
    &:first-child {
        &.childLevel {
            &:last-child {
                &::after {
                    left: auto;
                    border-radius: 0;
                    border-color: transparent #ccc transparent transparent;
                    transform: translate3d(1px, -2px, 0);
                }
            }
        }
        &::after {
            left: 50%;
            height: 15px;
            border: 2px solid;
            border-color: #ccc transparent transparent #ccc;
            border-radius: 6px 0 0 0;
            transform: translate3d(1px, 0, 0);
        }
        &::before {
            display: none;
        }
    }
    &:last-child {
        &::after {
            right: 50%;
            height: 15px;
            border: 2px solid;
            border-color: #ccc #ccc transparent transparent;
            border-radius: 0 6px 0 0;
            transform: translate3d(-1px, 0, 0);
        }
        &::before {
            display: none;
        }
    }
}

.node {
    position: relative;
    display: inline-block;
    margin: 0 1em;
    box-sizing: border-box;
    text-align: center;
    .leaf {
        z-index: 2;
        width: 10em;
        overflow: hidden;
        background-color: rgba(246, 247, 250, 1);
        padding: 8px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 6px;
        .icon {
            width: 2em;
        }
        .info {
            color: #000;
            font-size: 12px;
            text-align: left;
            div {
                margin: 2px 0px;
            }
        }
    }
    .hasMate {
        &::after {
            content: '';
            position: absolute;
            left: 2em;
            right: 2em;
            top: 2em;
            border-top: 2px solid #ccc;
            z-index: 1;
        }
    }
}

.vertical-line {
    width: 1px;
    height: 2em;
    background-color: #ccc;
    margin: 0px 6px;
}
</style>
